﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using NUnit.Framework;

namespace mebc4.tablebased.parallel
{
    [TestFixture]
    public class test_Runtime
    {
        // Processing of message is breadth first: split, tolower, map+, build+
        // Sending functional unit posts all output before it terminates and receiving FUs get their turn.
        [Test]
        public void Run()
        {
            using (var runtime = new MebcRuntime())
            {
                // register functional units
                // * wire them to input pins
                // * redirect their output to output pins
                runtime.Reg<string>("split.process", x => runtime.Post("split.result", SplitMap.Split(x)));

                runtime.Reg<IEnumerable<string>>("tolower.process", x => SplitMap.ToLower(x, o => runtime.Post("tolower.result", o)));

                runtime.Reg<string>("map.process", x => SplitMap.Map(x, o => runtime.Post("map.result", o)));

                var build = new Build();
                build.Result += x => runtime.Post("build.result", x);
                runtime.Reg<KeyValuePair<string, string>>("build.process", build.Process);

                var are = new AutoResetEvent(false);
                runtime.Reg<Dictionary<string, string>>("out", x => { Console.WriteLine("result: {0}, thread: {1}", x.Count, Thread.CurrentThread.GetHashCode()); are.Set(); });

                // map output pins to input pins
                runtime.Map("in", "split.process");
                runtime.Map("split.result", "tolower.process");
                runtime.Map("tolower.result", "map.process");
                runtime.Map("map.result", "build.process");
                runtime.Map("build.result", "out");

                runtime.Run(3);

                runtime.Post("in", "A=1;B=2");

                Assert.IsTrue(are.WaitOne(1000));
            }
        }
    }
}
